package com.example.dicomviewer;

import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import androidx.documentfile.provider.DocumentFile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

//import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
//import org.apache.commons.compress.archivers.zip.ZipFile;

/*
 * 用以拷贝文件的类
 * 主要在 FileInfoUtils中使用,用来对"下载内容"中的文件进行读取
 * */
public class FileUtil {
    private static final String TAG = "FileUtil";

    public static void copyFile(InputStream is, File dstFile) {
        try {

            BufferedInputStream bis = new BufferedInputStream(is);
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(dstFile), 1024);
            byte[] buf = new byte[1024];
            int c;
            c = bis.read(buf);
            while (c > 0) {
                bos.write(buf, 0, c);
                c = bis.read(buf);
            }
            bis.close();
            bos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String copyFileToCache(Context activity, File srcFile) {
        String desFilePath = activity.getExternalCacheDir() + "/" + srcFile.getName();
        File desFile = new File(desFilePath);
        if (desFile.exists())
            desFile.delete();
        try {
            InputStream inputStream = new FileInputStream(srcFile);
            copyFile(inputStream, desFile);      // 复制到本地路径
        } catch (IOException e) {
            e.printStackTrace();
        }
        return desFilePath;
    }

    /**
     * 用流拷贝文件一份到自己APP目录下
     *
     * @param context
     * @param uri
     * @param fileName
     * @return
     */
    public static String getPathFromInputStreamUri(Context context, Uri uri, String fileName) {
        InputStream inputStream = null;
        String filePath = null;
        if (uri.getAuthority() != null) {
            try {
                inputStream = context.getContentResolver().openInputStream(uri);
                File file = createTemporalFileFrom(context, inputStream, fileName);
                filePath = file.getPath();

            } catch (Exception e) {
                Log.e("FileUtils", e.toString());
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (Exception e) {
                    Log.e("FileUtils", e.toString());
                }
            }
        }

        return filePath;
    }

    private static File createTemporalFileFrom(Context context, InputStream inputStream, String fileName)
            throws IOException {
        File targetFile = null;

        if (inputStream != null) {
            int read;
            byte[] buffer = new byte[8 * 1024];
            //自己定义拷贝文件路径
            targetFile = new File(context.getExternalCacheDir(), fileName);
            if (targetFile.exists()) {
                targetFile.delete();
            }
            OutputStream outputStream = new FileOutputStream(targetFile);

            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            outputStream.flush();

            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return targetFile;
    }

    public static String getFileRealNameFromUri(Context context, Uri fileUri) {
        if (context == null || fileUri == null) return null;
        DocumentFile documentFile = DocumentFile.fromSingleUri(context, fileUri);
        if (documentFile == null) return null;
        return documentFile.getName();
    }

    public static void createDir(Context context, String dirType) {
        final File file = context.getExternalFilesDir(dirType);
        if (file == null) {
            throw new IllegalStateException("Failed to get external storage files directory");
        } else if (file.exists()) {
            if (!file.isDirectory()) {
                throw new IllegalStateException(file.getAbsolutePath() +
                        " already exists and is not a directory");
            }
        } else {
            if (!file.mkdirs()) {
                throw new IllegalStateException("Unable to create directory: " +
                        file.getAbsolutePath());
            }
        }
    }

    private static final String MAC_IGNORE = "__MACOSX/";

    public static void decompressFile(String target, String source) {
        if (TextUtils.isEmpty(target)) {
            return;
        }
        try {
            File file = new File(source);
            if (!file.exists()) {
                Log.d(TAG, "decompress error: file " + source + " not exists");
                return;
            }
            ZipFile zipFile = new ZipFile(file);
            ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));
            ZipEntry zipEntry = null;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                String fileName = zipEntry.getName();
                if (fileName != null && fileName.contains(MAC_IGNORE)) {
                    continue;
                }
                File temp = new File(target + File.separator + fileName);
                if (zipEntry.isDirectory()) {
                    File dir = new File(target + File.separator + fileName);
                    dir.mkdirs();
                    continue;
                }
                if (temp.getParentFile() != null && !temp.getParentFile().exists()) {
                    temp.getParentFile().mkdirs();
                }
                byte[] buffer = new byte[1024];
                OutputStream os = new FileOutputStream(temp);
                // 通过ZipFile的getInputStream方法拿到具体的ZipEntry的输入流
                InputStream is = zipFile.getInputStream(zipEntry);
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
                os.close();
                is.close();
            }
            zipInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
